package service

import (
	"errors"
	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	"gorm.io/gorm"
	"ssadmin/common/constant"
	"ssadmin/internal/admin/models"
	command "ssadmin/internal/admin/models/command"
	"ssadmin/internal/admin/models/query"
	"strings"

	cDto "ssadmin/common/query"
	"ssadmin/common/utils"
)

type User struct {
	service.Service
}

// GetPageByDept 根据权限分组查询用户
func (e *User) GetPageByDept(c *query.UserQuery, list *[]models.User, count *int64) error {
	data := models.User{}
	ud := models.UserDept{}
	udList := []models.UserDept{}

	deptIdSQL := "dept_id in (?)"
	deptIdSQLParams := []interface{}{c.DeptIds}

	//排除上级创建人
	notUserIdList := make([]string, 0)
	if err := e._getParent(c, &notUserIdList); err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return err
	}
	if len(notUserIdList) > 0 {
		deptIdSQL += " and user_id not in(?)"
		deptIdSQLParams = append(deptIdSQLParams, notUserIdList)
	}
	if err := ud.FindListByConds(e.Orm, &udList, deptIdSQL, deptIdSQLParams...); err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return err
	}
	userIdList := []string{}
	for _, dept := range udList {
		userIdList = append(userIdList, dept.UserId)
	}
	c.UserIds = userIdList

	//是否包含当前用户（通知的用户列表需要显示用户自己）
	if c.Self {
		c.UserIds = append(c.UserIds, c.CreatorId)
	}
	err := data.FindPage(e.Orm, &list, count,
		cDto.MakeCondition(c.GetNeedSearch()),
		cDto.OrderDest("create_time", true),
		cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
	)

	ru := models.UserRole{}
	for i, info := range *list {
		(*list)[i].CreateTime = info.CreateTimeDts.Format(utils.TIME_FMT_FULL)

		//获取每个用户的角色
		urList := []models.UserRole{}
		if err = ru.FindListByConds(e.Orm, &urList, "user_id=?", info.UserId); err == nil {
			//roldIds := []string{}
			//for _, userRole := range urList {
			//	roldIds = append(roldIds, userRole.RoleId)
			//}
			if len(urList) > 0 {
				(*list)[i].RoleId = urList[0].RoleId
			}
		}
	}
	return err
}

func (e *User) _getParent(c *query.UserQuery, userIdList *[]string) error {
	userMap := make(map[string]string)

	//循环获取上级用户
	userMap[c.CreatorId] = c.CreatorId
	tu := models.User{CreatorId: c.CreatorId}
	for len(tu.CreatorId) > 0 {

		//查询上级用户
		qparam := query.UserQuery{UserId: tu.CreatorId}
		tu.UserId = ""
		tu.CreatorId = ""
		if err := tu.FindBaseOne(e.Orm, &tu, cDto.MakeCondition(qparam)); err != nil {
			if !errors.Is(err, gorm.ErrRecordNotFound) {
				return err
			}
		}
		if len(tu.UserId) == 0 || tu.UserId == tu.CreatorId {
			break
		}
		userMap[tu.UserId] = tu.UserId
	}

	for k, _ := range userMap {
		//包含当前用户
		if c.Self && k == c.CreatorId {
			continue
		}
		*userIdList = append(*userIdList, k)
	}
	return nil
}

// GetByUsername 获取User对象
func (e *User) GetByUsername(username string, model *models.User) {
	if len(username) == 0 {
		return
	}
	e.Orm.First(model, "username = ? or mobile = ? ", username, username)
}

// ResetPassword 重置密码
func (e *User) ResetPassword(username string) error {
	data := models.User{}
	if err := data.ResetPassword(e.Orm, username); err != nil {
		return err
	}
	return nil
}

// Insert 创建User对象
func (e *User) Insert(c *command.UserInsertReq) error {
	userModel := models.User{}
	c.Generate(&userModel)

	if c.UserId == constant.AdminUser {
		userModel.IsAgency = constant.AgencyUser
		userModel.Agency = userModel.UserId
	}

	txErr := e.Orm.Transaction(func(tx *gorm.DB) error {
		if err := userModel.Add(tx, &userModel); err != nil {
			return err
		}
		//设置关联数据
		if err := e.setUserDept(&command.UserDept{
			UserId: userModel.UserId,
			DeptId: c.DeptIds,
		}, tx); err != nil {
			return err
		}

		if err := e.setUserRole(&command.UserRole{
			UserId: userModel.UserId,
			RoleId: c.RoleId,
		}, tx); err != nil {
			return err
		}
		return nil
	})

	return txErr
}

// Update 修改User对象
func (e *User) Update(c *command.UserUpdateReq) error {
	if len(c.UserId) == 0 {
		return errors.New("用户ID不能为空")
	}

	userModel := models.User{}
	id := query.UserQuery{UserId: c.UserId}
	where := cDto.MakeCondition(id)
	if err := userModel.FindOne(e.Orm, &userModel, where); err != nil {
		return err
	}

	c.Generate(&userModel)
	txErr := e.Orm.Transaction(func(tx *gorm.DB) error {
		if err := userModel.Mod(e.Orm, &userModel, where); err != nil {
			return err
		}

		// 需要置为空的字段特殊处理
		if c.Alias == "" {
			userMap := map[string]interface{}{
				"alias": "",
			}

			if err := userModel.Mod(e.Orm, &userMap, where); err != nil {
				return err
			}
		}

		if c.Avatar == "" {
			userMap := map[string]interface{}{
				"avatar": "",
			}

			if err := userModel.Mod(e.Orm, &userMap, where); err != nil {
				return err
			}
		}

		//不支持修改当前用户分组与角色
		if userModel.UserId == c.UserInfo[constant.CacheKeyUserId] {
			return nil
		}

		if c.DeptIds != "" {
			//设置关联数据
			if err := e.setUserDept(&command.UserDept{
				UserId: userModel.UserId,
				DeptId: c.DeptIds,
			}, tx); err != nil {
				return err
			}
		}

		if c.RoleId != "" {
			if err := e.setUserRole(&command.UserRole{
				UserId: userModel.UserId,
				RoleId: c.RoleId,
			}, tx); err != nil {
				return err
			}
		}

		return nil
	})

	env.Log.Errorf("user update error . %v", txErr)
	return txErr
}

// UpdatePwd 修改密码
func (e *User) UpdatePwd(c *command.PasswordUpdateReq) error {
	var userInfo models.User
	e.GetByUsername(c.Username, &userInfo)

	if len(userInfo.UserId) == 0 {
		return errors.New("用户不存在")
	}

	if userInfo.Password != utils.Md5Pwd(c.Password, userInfo.Username+c.Password) {
		return errors.New("密码错误")
	}

	userInfo.Password = utils.Md5Pwd(c.NewPassword, userInfo.Username+c.NewPassword)
	err := userInfo.Mod(e.Orm, &userInfo, cDto.MakeCondition(query.UserQuery{
		UserId: userInfo.UserId,
	}))
	return err
}

// UpdatePwdByPhone 修改密码
func (e *User) UpdatePwdByPhone(c *command.PasswordUpdateReq) error {
	var userInfo models.User
	userInfo.Password = utils.Md5Pwd(c.NewPassword, c.Username+c.NewPassword)
	err := userInfo.Mod(e.Orm, &userInfo, cDto.MakeCondition(query.UserQuery{
		Username: c.Username,
	}))
	return err
}

func (e *User) setUserDept(c *command.UserDept, tx *gorm.DB) error {
	//删除关联数据
	ud := models.UserDept{}
	tx.Model(ud).Where("user_id in (?)", c.UserId).Delete(ud)

	//插入关联数据
	deptList := []models.UserDept{}
	deptIds := strings.Split(c.DeptId, ",")
	for _, id := range deptIds {
		deptList = append(deptList, models.UserDept{
			UserId: c.UserId,
			DeptId: id,
		})
	}
	return tx.Model(ud).Create(&deptList).Error
}

func (e *User) setUserRole(c *command.UserRole, tx *gorm.DB) error {
	var ur = models.UserRole{}
	//删除关联数据
	tx.Model(ur).Where("user_id=?", c.UserId).Delete(ur)

	//插入关联数据
	var roleList []models.UserRole
	roleIds := strings.Split(c.RoleId, ",")
	for _, id := range roleIds {
		roleList = append(roleList, models.UserRole{
			UserId: c.UserId,
			RoleId: id,
		})
	}
	return tx.Model(ur).Create(&roleList).Error
}

// Remove 删除User
func (e *User) Remove(d *command.UserDeleteReq) error {
	if len(d.GetId()) == 0 {
		return errors.New("用户ID不能为空")
	}

	txErr := e.Orm.Transaction(func(tx *gorm.DB) error {
		data := models.User{}
		userList := []models.User{}
		if err := data.FindListByConds(tx, &userList, "id in (?)", d.GetId()); err != nil {
			return err
		}
		for _, user := range userList {
			if user.UserId == d.CurrentUserId {
				return errors.New("不能删除当前登录用户")
			}
		}

		if err := data.Del(tx, "id in (?)", d.GetId()); err != nil {
			return err
		}

		ur := models.UserRole{}
		if err := ur.Del(tx, &ur, "user_id in (?)", d.GetId()); err != nil {
			return err
		}

		ud := models.UserDept{}
		if err := ur.Del(tx, &ud, "user_id in (?)", d.GetId()); err != nil {
			return err
		}

		return nil
	})

	return txErr
}

func (e *User) CheckCode(d *command.PasswordForgetResetReq) error {
	//校验验证码
	vs := VerifyCode{}
	if err := vs.ValidCode(d); err != nil {
		return err
	}
	return nil
}
